﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Timers;
using System.Collections;
using Reborn_Server.App1AppHandler;
using App1AppHandler;
using Reborn_WorldServer;
using Reborn_WorldServer.App1AppHandler;

namespace Reborn_Server.App1AppHandler
{
    public class HealingPotion : Buff, IConsumable
    {
        //Minor Healing Potion
        public int healingPotionMax = 1000;
        //1.5 Min cooldown
        public int healingPotionDuration = 90;

        //Lesser Healing Potion
        public int lesserHealingPotionMax = 2000;
        //3 Minute Cooldown
        public int lesserHealingPotionDuration = 180;


        //Minor Healing Shot
        public int minorHealingShotMax = 750;
        //1 Min cooldown
        public int minorHealingShotDuration = 60;


        public int currentHealing = 0;

        public void setDuration(SpellIcon icon)
        {
            if (icon.Name.IndexOf("Lesser") > -1)
            {
                if (icon.Name.IndexOf("Shot") > -1)
                {
                    
                }
                else
                {
                    minutesLeft = System.Convert.ToInt32(Math.Ceiling(lesserHealingPotionDuration / 60.00));
                    ticksLeft = lesserHealingPotionDuration;
                }
            }
            //Minor
            else
            {
                if (icon.Name.IndexOf("Shot") > -1)
                {
                    minutesLeft = System.Convert.ToInt32(Math.Ceiling(minorHealingShotDuration / 60.00));
                    ticksLeft = minorHealingShotDuration;
                }
                else
                {
                    minutesLeft = System.Convert.ToInt32(Math.Ceiling(healingPotionDuration / 60.00));
                    ticksLeft = healingPotionDuration;
                }
            }
        }

        public int getMaxHealing()
        {
            if (spellIcon.Name.IndexOf("Lesser") > -1)
                return lesserHealingPotionMax;
            //Minor
            else
            {
                if (spellIcon.Name.IndexOf("Shot") > -1)
                    return minorHealingShotMax;
                else
                    return healingPotionMax;
            }
        }

        public int getPotionIncrement()
        {
            if (spellIcon.Name.IndexOf("Lesser") > -1)
                return 200;
            //Minor
            else
            {
                if (spellIcon.Name.IndexOf("Shot") > -1)
                    return 75;
                else
                    return 100;
            }
        }

        //Total Healing  50 ticks X 20  1000
        public HealingPotion() 
        {
            spellTimer.Interval = 1000;
        }

        public bool MeetsConsumeRequirements(Character myCharacter, Loot lootitem)
        {
            if (myCharacter.buffManager.GetBuff(lootitem.Name) != null)
            {
                myCharacter.SendMessage("Potion has no effect. Your still waiting on your last potions after effects to wear off!", "server");
                myCharacter.PlaySound("Ding", myCharacter.MapX, myCharacter.MapY);
                return false;
            }
            if (lootitem.Name.IndexOf("Shot") > -1 && myCharacter.buffManager.GetBuffByStackType("ShotPotion") != null)
            {
                myCharacter.SendMessage("Potion has no effect. Your still waiting on your last potions after effects to wear off!", "server");
                myCharacter.PlaySound("Ding", myCharacter.MapX, myCharacter.MapY);
                return false;
            }


            return true;
        }

        public void Consume(Character myCharacter, Loot lootitem)
        {
            TargetCreatureBase = myCharacter;

            LockItem lockItem = TargetCreatureBase.GameHandler.GetLockItem(TargetCreatureBase.MapID, TargetCreatureBase.Instance);
            lock (lockItem.LockObj)
            {
                //CHECK IF WE'RE IN A VALID STATE TO CONTINUE EXECUTION/////////////////////////

                //System.Reflection.MethodBase currentMethodBase = System.Reflection.MethodBase.GetCurrentMethod();
                //Delegate currentMethodDelegate = Delegate.CreateDelegate(currentMethodBase.GetType(), this, currentMethodBase.Name);

                //Create a delegate for this method incase it cant be run right now
                Action<Character, Loot> thisMethod = (Action<Character, Loot>)Consume;
                //Record this method's arguments
                Object[] thisMethodArgs = { myCharacter, lootitem };
                //Pass the delegate and args when we check if we're mid map transfer. If yes, they will be recorded and run again automatically.
                if (TargetCreatureBase.isChangingMaps(thisMethod, thisMethodArgs) == true)
                    return;

                //A map transfer happened, but its already complete. Immediately re-run this method on a different thread. 
                //We need to use a different thread because otherwise the current thread would lock 2 maps possibly resulting in a deadlock.
                if (TargetCreatureBase.MapID != lockItem.MapID)
                {
                    thisMethod.BeginInvoke(myCharacter, lootitem, null, null);
                    return;
                }
                //STATE IS VALID, CONTINUE EXECUTION///////////////////////////////////////////

                foreach (MapItem mapitem in TargetCreatureBase.currentMapItem.mapItemsWithin8)
                {
                    foreach (CreatureBase creaturebase in mapitem.CreaturesBases)
                    {
                        if (creaturebase is Character)
                        {
                            Character character = (Character)creaturebase;
                            character.PlaySound("DrinkBottle", myCharacter.MapX, myCharacter.MapY);
                        }
                    }
                }

                if (lootitem.Name.IndexOf("Healing") > -1 &&
                    TargetCreatureBase.HP >= TargetCreatureBase.MaxHP)
                    return;
                else if
                    (lootitem.Name.IndexOf("Stamina") > -1 &&
                    TargetCreatureBase.Stamina >= TargetCreatureBase.MaxStamina)
                    return;
                else if
                    (lootitem.Name.IndexOf("Magic") > -1 &&
                    TargetCreatureBase.Mana >= TargetCreatureBase.MaxMana)
                    return;


                SpellIcon healPotion = new SpellIcon();
                this.SpellID = TargetCreatureBase.GameHandler.ItemIDGen.GetSpellID();
                healPotion.ClassName = lootitem.ClassName;
                healPotion.Description = lootitem.Description;
                healPotion.ImageURL = lootitem.ImageURL;
                healPotion.Name = lootitem.Name;
                healPotion.Offensive = true;
                healPotion.CastType = "Self";

                if (lootitem.Name.IndexOf("Shot") > -1)
                    healPotion.StackType = "ShotPotion";

                this.spellIcon = healPotion;
                this.SpellID = Managers.GameHandler.ItemIDGen.GetSpellID();
                setDuration(healPotion);

                TargetCreatureBase.buffManager.AddBuff(this);
                TargetCreatureBase.buffManager.UpdateBuffs();

            }
            spellTimer.Start();
        }

        override protected void SpellTimer_Expired(object source, ElapsedEventArgs e)
        {
            int oldMinutesLeft = System.Convert.ToInt32(Math.Ceiling(ticksLeft / 60.00));

            ticksLeft--;

            LockItem lockitem = TargetCreatureBase.GameHandler.GetLockItem(TargetCreatureBase.MapID, TargetCreatureBase.Instance);
            lock (lockitem.LockObj)
            {
                //CHECK IF WE'RE IN A VALID STATE TO CONTINUE EXECUTION/////////////////////////

                //Create a delegate for this method incase it cant be run right now
                Action<object, ElapsedEventArgs> thisMethod = (Action<object, ElapsedEventArgs>)SpellTimer_Expired;
                //Record this method's arguments
                Object[] thisMethodArgs = { source, e };
                //Pass the delegate and args when we check if we're mid map transfer. If yes, they will be recorded and run again automatically.
                if (TargetCreatureBase.isChangingMaps(thisMethod, thisMethodArgs))
                {
                    //Re-Increment the counter since this method will be re-invoked after the transfer.
                    ticksLeft++;
                    return;
                }
                //A map transfer happened, but its already complete. Immediately re-run this method on a different thread. 
                //We need to use a different thread because otherwise the current thread would lock 2 maps possibly resulting in a deadlock.
                if (TargetCreatureBase.MapID != lockitem.MapID)
                {
                    //Re-Increment the counter since this method will be re-invoked after the transfer.
                    ticksLeft++;

                    thisMethod.BeginInvoke(source, e, null, null);
                    return;
                }
                //STATE IS VALID, CONTINUE EXECUTION///////////////////////////////////////////

                //This buff has been removed, do nothing (this can occur if the buff gets overwritten exactly when this timer fires)
                if (TargetCreatureBase.buffManager.hasBuff(this.SpellID) == false)
                    return;

                if (spellIcon.Name.IndexOf("Healing") > -1 && TargetCreatureBase.HP >= TargetCreatureBase.MaxHP)
                    currentHealing = getMaxHealing();
                else if (spellIcon.Name.IndexOf("Stamina") > -1 && TargetCreatureBase.Stamina >= TargetCreatureBase.MaxStamina)
                    currentHealing = getMaxHealing();
                else if (spellIcon.Name.IndexOf("Magic") > -1 && TargetCreatureBase.Mana >= TargetCreatureBase.MaxMana)
                    currentHealing = getMaxHealing(); 

                if (TargetCreatureBase.HP < 1)
                {
                    RemoveSpell(true, false);
                    return;
                }

                if (currentHealing < getMaxHealing())
                {
                    currentHealing = currentHealing + getPotionIncrement();

                    if (spellIcon.Name.IndexOf("Healing") > -1)
                        TargetCreatureBase.HP = TargetCreatureBase.HP + getPotionIncrement();
                    else if (spellIcon.Name.IndexOf("Stamina") > -1)
                        TargetCreatureBase.Stamina = TargetCreatureBase.Stamina + getPotionIncrement();
                    else if (spellIcon.Name.IndexOf("Magic") > -1)
                        TargetCreatureBase.Mana = TargetCreatureBase.Mana + getPotionIncrement(); 

                    TargetCreatureBase.Update_Character();
                }

                foreach (MapItem mapitem in TargetCreatureBase.currentMapItem.mapItemsWithin4)
                {
                    foreach (CreatureBase creatureBase in mapitem.CreaturesBases)
                    {
                        if (creatureBase is Character)
                        {
                            Character character = (Character)creatureBase;

                            if (spellIcon.Name.IndexOf("Healing") > -1)
                                character.UpdateCreatureBaseHp(TargetCreatureBase);
                            else if (spellIcon.Name.IndexOf("Stamina") > -1)
                                character.UpdateCreatureBaseStamina(TargetCreatureBase);
                            else if (spellIcon.Name.IndexOf("Magic") > -1)
                                character.UpdateCreatureBaseMana(TargetCreatureBase);
                        }
                    }
                }

                if (ticksLeft == 0)
                {
                    RemoveSpell(true, false);
                    return;
                }
                else
                    spellTimer.Start();

                minutesLeft = System.Convert.ToInt32(Math.Ceiling(ticksLeft / 60.00));
                if (oldMinutesLeft != minutesLeft)
                    TargetCreatureBase.buffManager.UpdateBuffs();
            }
        }
    }
}
